import { _decorator, Component, Node, Prefab, instantiate, sys, LabelComponent, director, resources, SpriteFrame, Sprite } from 'cc';
import { PlayerBox } from './PlayerBox/PlayerBox';
import { SceneFlag } from './SceneFlag';
import { getNet, record } from './Other/Util'
import { NetWorkManager } from './NetWorkManager';
import _ from 'lodash';
import { CardReverser } from './CardReverser';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = GameRoomDirector
 * DateTime = Tue Feb 08 2022 19:26:00 GMT+0800 (中国标准时间)
 * Author = awi1299
 * FileBasename = GameRoomDirector.ts
 * FileBasenameNoExtension = GameRoomDirector
 * URL = db://assets/script/GameRoomDirector.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
 *
 */

@ccclass('GameRoomDirector')
export class GameRoomDirector extends Component {
    // [1]
    // dummy = '';

    @property(LabelComponent)
    roomInfo: LabelComponent

    @property(Node)
    desk: Node

    @property(Prefab)
    card: Prefab

    @property(Node)
    buttonStart: Node

    @property(Node)
    buttonEnd: Node

    @property(Node)
    buttonNext:Node

    start() {
        const net = getNet()
        net.curScene = SceneFlag.GAME
        this.connect()
    }

    onDestroy() {
        const net = getNet()
        if (net.room) {
            record()//记录session
        }
    }

    async connect() {
        const net = getNet()
        try {
            if (net.isReconnect) {
                net.isReconnect = false
                net.room = await net.client.reconnect(sys.localStorage.getItem('roomId'), sys.localStorage.getItem('sessionId'))
            } else if (net.joinRoomId) {
                const id = parseInt(net.joinRoomId)
                if (id > 9999 || id < 0) {
                    console.log(`错误id: ${id}`)
                    return
                }
                net.room = await net.client.joinById(net.joinRoomId)
            } else {
                net.room = await net.client.create('my_room')
            }

            console.log("joined successfully!");
            console.log("user's sessionId:", net.room.sessionId);

            //如果已经切换场景则不再监听房间
            if (net.curScene !== SceneFlag.GAME) return

            net.room.onStateChange((state) => {
                const cur = Array.from<string>(state.players.keys())[state.cur]
                if(cur != net.room.sessionId)this.buttonNext.active = false
                else this.buttonNext.active = true
                this.roomInfo.string = `当前: ${cur.slice(0, 4)}... 房间号: ${net.room.id} 人数:${state.players.size} 你的ID: ${net.room.sessionId.slice(0, 4)}...`
            });
            net.room.onLeave((code) => {
                console.log("onLeave:", code);
            });

            //监听玩家加入
            // net.room.state.players.onAdd = (player, sessionId) => {
            //     const node = instantiate(this.playerBoxPrefab)
            //     node.name = sessionId
            //     node.getComponent(PlayerBox).displayName()
            //     this.playerBoxes.addChild(node)
            //     console.log('add a playernode')

            //     //监听玩家连接状态
            //     player.listen('connected',(curV,preV)=>{
            //         node.getComponent(PlayerBox).changeConnect(curV)
            //     })
            // }
            // net.room.state.players.onRemove = (player, sessionId) => {
            //     this.playerBoxes.removeChild(this.playerBoxes.getChildByName(sessionId))
            // }

            net.room.state.players.onAdd = (player, key) => {
                if (player.name != net.room.sessionId) return
                console.log(player)
                console.log('onAdd')
                player.cardsOfPlayer.onAdd = (card, key) => {
                    console.log(card.val)
                    this.renewCards(card)
                }

                player.cardsOfPlayer.onRemove = (card) =>{
                    this.desk.removeAllChildren()
                }
            }

            net.room.state.players.onChange = (player, key) => {
                console.log(player, 'has change on', key)
            }

            //监听游戏开始结束
            net.room.state.listen('isGaming', cur => {
                if (cur) {
                    this.buttonStart.active = false
                    this.buttonEnd.active = true
                } else {
                    this.buttonStart.active = true
                    this.buttonEnd.active = false
                }
            })

            record()//记录session
            console.log(`join ${net.room.id} successfully`)
        } catch (e) {
            console.error(e);
            director.loadScene(SceneFlag.LOBBY)
        }
    }


    renewCards(card) {
        //生成新的卡牌节点
        const node = instantiate(this.card)
        resources.load(`image/${card.color ? '黑' : '白'}牌/spriteFrame`, SpriteFrame, (e, img) => {
            node.getComponent(Sprite).spriteFrame = img
            node.getComponent(CardReverser).cardBack = img
            if (e) console.error(e)
        })
        resources.load(`image/${card.color ? '黑' : '白'}牌${card.val}/spriteFrame`, SpriteFrame, (e, img) => {
            node.getComponent(CardReverser).cardFront = img
            if (e) console.error(e)
        })
        this.desk.addChild(node)

        //重连恢复卡牌状态
        const cardControler = node.getComponent(CardReverser)
        cardControler.isExpose = card.isExpose
        if (cardControler.isExpose) cardControler.toFront()

        //重排序
        node.name = `${card.val}${card.color}`
        const table = []
        this.desk.children.forEach(val => table.push([val.name, parseInt(val.name)]))
        table.sort((a, b) => a[1] - b[1])
        for (let i of _.range(table.length)) {
            this.desk.getChildByName(table[i][0]).setSiblingIndex(i)
        }

        //log
        console.log(this.desk.children)
        console.log(node)
        console.log('新的卡片')
    }

    clickReturnToLobby() {
        const net = getNet()
        director.loadScene(SceneFlag.LOBBY)
        net.room.removeAllListeners()
        net.room.connection.close()
    }

    clickStartGame() {
        const net = getNet()
        if (net.room.state.players.size < 2) {
            return
        }
        if (net.room.state.host !== net.room.sessionId) {
            return
        }
        net.room.send('start')
    }

    clickNext() {
        const net = getNet()
        net.room.send('turn')
    }

    clickEnd() {
        const net = getNet()
        net.room.send('end')
    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html
 */
